#include "fileops.h"
#define MAXSTRNUM 6

int TapesLoc[MAXTAPE]={0};
int lastTape=-1;
int currTape;
int fd = NULL;
int errno;

//func_directory_initial_scan

//func_read_curr_tape(buff_size)
/*Reading the Current Tape, buff_size of bytes*/
int read_current_tape(char* buffer,int buff_size){
	int curPos;
	int status;
	if(fd == NULL || currTape == -1){
		perror("error no tape loaded\n");
		return -1;
	}

	status = read(fd, buffer, buff_size);

	if(0 > status){
		perror("error reading tape\n");
		return -1;
	}
	/*updating TapeLoc*/
	curPos = lseek(fd,0,SEEK_CUR);
	TapesLoc[currTape] = curPos;
	printf("read_current_tape(): read %d bytes - %s\n",status,buffer);
	return status;
}

//func_write_curr_tape(buff)
int write_current_tape(const char* buffer, int size){
int status=0,curPos;
if(fd == NULL || currTape == -1){
	perror("error no tape loaded\n");
	return -1;
}

status = write(fd, buffer,size);

if(status < 0){
	perror("error writing to tape\n");
	return -1;
}

/*updating TapeLoc*/
curPos = lseek(fd, 0, SEEK_CUR);
TapesLoc[currTape] = curPos;
printf("write_current_tape(): wrote - %s, status=%d\n",buffer, status);
return status;
}

//func_create_tape
/*creating a new tape, assuming current tape isn't changed*/
int create_tape(){
	FILE* tempfd;
	char fname[MAXSTRNUM+4] = "TAPE";
	char stapeNum[MAXSTRNUM];
	char cmd1[6+MAXSTRNUM+4];
	char cmd2[8+2*(MAXSTRNUM+4)];
	sprintf(stapeNum,"%d",lastTape+1);
	strcat(fname,stapeNum);

	if(lastTape > MAXTAPE){
		printf("error tape capacity reached\n");
	}
	printf("creating tape..\n");
	tempfd = fopen(fname,"w+");
	if(NULL == tempfd){
		printf("error creating new tape\n");
		return -1;
	}
	fclose(tempfd);
	tempfd = NULL;

#ifdef ZIPME
	/*zipping the file*/
	if(mybzip(lastTape+1)){
		printf("error zipping\n");
		return -1;
	}
#endif

	/*updating TapesLoc*/
	TapesLoc[lastTape+1] = 0;
	++lastTape;

	return lastTape;
}


//func_replace_tape (tape_number)
int replace_tape(int tape_num){
	char fname[MAXSTRNUM+4] = "TAPE";
	char stapeNum[MAXSTRNUM];
	if(0 > TapesLoc[tape_num]){
		printf("error replacing to a non existing tape\n");
		return -1;
	}
	sprintf(stapeNum,"%d",tape_num);
	strcat(fname,stapeNum);

	if(fd != NULL) {
		printf("Closing fd %d\n", fd);
		close(fd);
		fd = NULL;
#ifdef ZIPME
		/*zipping the closing tape */
		if(mybzip(currTape)){
			printf("error zipping\n");
			return -1;
		}
#endif
		currTape = -1;
	}
#ifdef ZIPME
	/*unzipping the opening tape*/
	if(mybunzip(tape_num)){
		printf("error unzipping\n");
		return -1;
	}
#endif

	fd = open(fname, O_RDWR);
	printf("fd: %d, tape_num=%d\n",fd,tape_num);
	if(fd == NULL){
		printf("error opening tape number: %d\n",tape_num);
		return -1;
	}
	currTape = tape_num;
	printf("curr_offset = %d\n",TapesLoc[tape_num]);
	lseek(fd,TapesLoc[tape_num],SEEK_SET);
	return 0;
}




//func_rewind_curr_tape
int rewind_current_tape(){
if(fd == NULL || currTape == -1){
perror("error no tape is loaded\n");
return -1;
}
lseek(fd, 0, SEEK_SET);
TapesLoc[currTape] = 0;
return 0;
}

//func_delete_tape(tape_number)
int delete_tape(int tape_num){
char fname[MAXSTRNUM+4] = "TAPE";
char stapeNum[MAXSTRNUM];
sprintf(stapeNum,"%d",tape_num);
strcat(fname,stapeNum);
if(tape_num == currTape){

close(fd);
fd = NULL;
currTape = -1;
}
if((tape_num <= lastTape) && (TapesLoc[tape_num] < 0)) {
perror("error tape was allready deleted\n");
return -1;
}
if(tape_num > lastTape){
perror("error there's no such tape\n");
return -1;
}
if(0 != remove(fname)){
perror("error deleting tape\n");
return -1;
}
TapesLoc[tape_num] = -1;
return 0;
}

int mybzip(int tape_num){
	char cmd1[6+MAXSTRNUM+4];
	char cmd2[8+2*(MAXSTRNUM+4)];
	char fname[MAXSTRNUM +4];
	sprintf(fname,"TAPE%d",tape_num);

	sprintf(cmd1,"bzip2 %s",fname);
	if(-1 == system(cmd1)){
		printf("error on zipping");
		return -1;
	}
	sprintf(cmd2,"mv %s.bz2 %s",fname,fname);
	if(-1 == system(cmd2)){
		printf("error on renaming\n");
		return -1;
	}

	return 0;

}

int mybunzip(int tape_num){
	char cmd1[8+2*(MAXSTRNUM+4)];
	char cmd2[12+MAXSTRNUM+4];
	char fname[MAXSTRNUM + 4];
	sprintf(fname,"TAPE%d",tape_num);

	sprintf(cmd1,"mv %s %s.bz2",fname,fname);
	if(-1 == system(cmd1)){
		printf("error on renaming\n");
		return -1;
	}
	sprintf(cmd2,"bunzip2 %s.bz2",fname);
	if(-1 == system(cmd2)){
		printf("error on unzipping\n");
		return -1;
	}
	return 0;
}

int shutting_down(){
	if(fd != NULL) {
			printf("Closing fd %d\n", fd);
			close(fd);
			fd = NULL;
	#ifdef ZIPME
			/*zipping the closing tape */
			if(mybzip(currTape)){
				printf("error zipping\n");
				return -1;
			}
	#endif
			currTape = -1;
		}
}

//func_directory_initial_scan
//returns -1 for failing , otherwise return the largest index of existing tape
int investigate_tape_lib(){
    DIR *dir = NULL;
    FILE * tape;
    struct dirent * dir_enteries = NULL;
    int i;
    int max_index = -1;
    int suffix = 0;

    //now we assume that we already changed the working dir in main to be the one we want

    if((dir = opendir(".")) == NULL){
        printf("directory was open ");
        perror("error opening dir");
        return -1;
    }
    while((dir_enteries = readdir(dir)) != NULL){

        if ((0 == strcmp(dir_enteries->d_name, ".")) ||
               (0 == strcmp(dir_enteries->d_name, "..")))
                continue;

       
        sscanf(dir_enteries->d_name ,"TAPE%d",&suffix);
             TapesLoc[suffix] = 1;
            
            if(suffix >= max_index){
            max_index = suffix;
          }
	
      }
	for(i=0; i<=MAXTAPE ; i++){
		if(TapesLoc[i] == 1)
			printf("%d " ,i);
	}
	printf("%d " , max_index);

lastTape = max_index;

	for (i=0; i<=max_index; TapesLoc[i++]--);

return 0;
}


